﻿using System;
using GeoAPI.Geometries;

namespace NetTopologySuite.Geometries.Implementation
{
	[Serializable]
	public class DotSpatialAffineCoordinateSequenceFactory : ICoordinateSequenceFactory
	{
		private DotSpatialAffineCoordinateSequenceFactory() : this(Ordinates.XYZM)
		{
		}

		public DotSpatialAffineCoordinateSequenceFactory(Ordinates ordinates)
		{
			this._ordinates = (Ordinates.XY | ordinates);
		}

		public static DotSpatialAffineCoordinateSequenceFactory Instance
		{
			get
			{
				object instanceLock = DotSpatialAffineCoordinateSequenceFactory.InstanceLock;
				DotSpatialAffineCoordinateSequenceFactory result;
				lock (instanceLock)
				{
					DotSpatialAffineCoordinateSequenceFactory dotSpatialAffineCoordinateSequenceFactory;
					if ((dotSpatialAffineCoordinateSequenceFactory = DotSpatialAffineCoordinateSequenceFactory._instance) == null)
					{
						dotSpatialAffineCoordinateSequenceFactory = (DotSpatialAffineCoordinateSequenceFactory._instance = new DotSpatialAffineCoordinateSequenceFactory());
					}
					result = dotSpatialAffineCoordinateSequenceFactory;
				}
				return result;
			}
			set
			{
				DotSpatialAffineCoordinateSequenceFactory._instance = value;
			}
		}

		public ICoordinateSequence Create(Coordinate[] coordinates)
		{
			return new DotSpatialAffineCoordinateSequence(coordinates, this.Ordinates);
		}

		public ICoordinateSequence Create(ICoordinateSequence coordSeq)
		{
			return new DotSpatialAffineCoordinateSequence(coordSeq, this.Ordinates);
		}

		public ICoordinateSequence Create(int size, int dimension)
		{
			return new DotSpatialAffineCoordinateSequence(size, this.Ordinates & OrdinatesUtility.DimensionToOrdinates(dimension));
		}

		public ICoordinateSequence Create(int size, Ordinates ordinates)
		{
			return new DotSpatialAffineCoordinateSequence(size, this.Ordinates & ordinates);
		}

		public ICoordinateSequence Create(double[] xy)
		{
			return new DotSpatialAffineCoordinateSequence(xy, null);
		}

		public ICoordinateSequence Create(double[] xy, double[] zm, bool isMeasure = false)
		{
			if (isMeasure)
			{
				return new DotSpatialAffineCoordinateSequence(xy, null, zm);
			}
			return new DotSpatialAffineCoordinateSequence(xy, zm);
		}

		public ICoordinateSequence Create(double[] xy, double[] z, double[] m)
		{
			return new DotSpatialAffineCoordinateSequence(xy, z, m);
		}

		public Ordinates Ordinates
		{
			get
			{
				return this._ordinates;
			}
		}

		private static DotSpatialAffineCoordinateSequenceFactory _instance;

		private static readonly object InstanceLock = new object();

		private readonly Ordinates _ordinates;
	}
}
